﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Serialization.Formatters;
using System.Security.Cryptography;
using System.Collections;
using System.Data;
using System.Data.Common ;
using Keel.ORM;
using Keel.DB;
using System.Runtime.InteropServices;

namespace Keel
{
    public class DBHelper<T>
    {
        DBOperator<Keel.IDatabase> idb=null ;
        /// <summary>
        /// 使用通用数据库，即 Keel.DB.Common.NowDataBase,在程序启动时需要为此赋值
        /// </summary>
        /// <exception cref="Keel.DB.DataBaseNotConfigException">当没有为Keel.DB.Common.NowDataBase复制时会抛出此错误</exception>
        public DBHelper()
        {
            idb = new DBOperator<IDatabase>(new Keel.DB.Common());
        }
        /// <summary>
        /// 使用制定的数据库新建DBHelper
        /// </summary>
        /// <param name="db"></param>
        public DBHelper(Keel.IDatabase db)
        {
            idb = new DBOperator<IDatabase>(db);
        }
        #region 控件处理部分
        /// <summary>
        /// 提取Model 
        /// </summary>
        /// <param name="ctl">控件</param>
        /// <returns></returns>
        public T Distill(System.Windows.Forms.Control ctl)
        {
            T md = System.Activator.CreateInstance<T>();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                object value = null;
                Type t = Keel.MetaType.GetMetaTypeFromDbType((DbType)Enum.Parse(typeof(DbType), dfa.DBType)).ClassType; 
                if (t.Equals(typeof(string)))
                {
                  if (ctl.Controls.ContainsKey("txt" +dfa.ColumnName ))
                  {
                    value =   ((ctl.Controls["txt" + dfa.ColumnName]) as System.Windows.Forms.TextBox).Text  ;

                  }
                }
                else if (t.Equals(typeof(DateTime)))
                {
                    if (ctl.Controls.ContainsKey("dtp" + dfa.ColumnName))
                    {
                       value =  (ctl.Controls["dtp" + dfa.ColumnName] as System.Windows.Forms.DateTimePicker).Value ;
                    }
                }

                else if (t.Equals(typeof(decimal)) || t.Equals(typeof(Int32)) || t.Equals(typeof(float)) || t.Equals(typeof(double))
                    || t.Equals(typeof(byte)) || t.Equals(typeof(int)) || t.Equals(typeof(Int16)) || t.Equals(typeof(Int64))
                    )
                {
                    if (ctl.Controls.ContainsKey("nud" + dfa.ColumnName))
                    {
                      value = System.Convert.ChangeType(   (ctl.Controls["nud" + dfa.ColumnName ]as System.Windows.Forms.NumericUpDown).Value,t );
                    }
                }
                else
                {
                    if (ctl.Controls.ContainsKey("txt_unsupport_type_" + dfa.ColumnName))
                    {
                       value = ((ctl.Controls["txt_unsupport_type_" + dfa.ColumnName]) as System.Windows.Forms.TextBox).Text;
                    }
                }
                item.SetValue(md,value,null   );
            }
            return md;
        }
        /// <summary>
        /// 填充控件
        /// </summary>
        /// <param name="ctl">被填充控件</param>
        /// <param name="SetValue">Model</param>
        /// <returns>总是返回真,如果不出错误则直接返回真</returns>
        public bool Fill( System.Windows.Forms.Control ctl,T SetValue)
        {
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                object   objset = item.GetValue(SetValue, null)  ;
                if (objset == null)
                {
                    continue;
                }
                Type t = Keel.MetaType.GetMetaTypeFromDbType((DbType)Enum.Parse(typeof(DbType), dfa.DBType)).ClassType; 
                if (t.Equals(typeof(string)))
                {
                  if (ctl.Controls.ContainsKey("txt" +dfa.ColumnName ))
                  {
                      ((ctl.Controls["txt" + dfa.ColumnName]) as System.Windows.Forms.TextBox).Text = objset as string ;

                  }
                }
                else if (t.Equals(typeof(DateTime)))
                {
                    if (ctl.Controls.ContainsKey("dtp" + dfa.ColumnName))
                    {
                        (ctl.Controls["dtp" + dfa.ColumnName] as System.Windows.Forms.DateTimePicker).Value = (DateTime)objset ;
                    }
                }

                else if (t.Equals(typeof(decimal)) || t.Equals(typeof(Int32)) || t.Equals(typeof(float)) || t.Equals(typeof(double))
                    || t.Equals(typeof(byte)) || t.Equals(typeof(int)) || t.Equals(typeof(Int16)) || t.Equals(typeof(Int64))
                    )
                {
                    if (ctl.Controls.ContainsKey("nud" + dfa.ColumnName))
                    {
                        decimal ddd;
                          if (decimal.TryParse(objset.ToString (),out ddd ))
                          {
                              (ctl.Controls["nud" + dfa.ColumnName] as System.Windows.Forms.NumericUpDown).Value = ddd;
                          }
                    }
                }
                else
                {
                    if (ctl.Controls.ContainsKey("txt_unsupport_type_" + dfa.ColumnName))
                    {
                        ((ctl.Controls["txt_unsupport_type_" + dfa.ColumnName]) as System.Windows.Forms.TextBox).Text = objset as string;
                    }
                }
            }
            return true;
          
        }
        #endregion 


        #region 视图处理部分  目前没有加异常处理，如碰到非视图时的异常
        /// <summary>
        /// 查询出制定视图的所有值，SQL语句在生成此视图时已赋值
        /// </summary>
        /// <returns></returns>
        public List<T> GetDataViewForObjectList()
        {
            List<T> lt = new List<T>();
            string viewname = ((Keel.ORM.DataViewAttribute)((typeof(T)).GetCustomAttributes(typeof(Keel.ORM.DataViewAttribute), true)[0])).ViewName;
            string sql = Encoding.Default.GetString(Convert.FromBase64String(((Keel.ORM.DataViewAttribute)((typeof(T)).GetCustomAttributes(typeof(Keel.ORM.DataViewAttribute), true)[0])).SQLString));
            DbDataReader dr = idb.GetDataReader(sql);
            while ((dr.Read()))
            {

                T t = Activator.CreateInstance<T>();
                foreach (var item in typeof(T).GetProperties())
                {
                    string colname = ((Keel.ORM.DataFieldAttribute)item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0]).ColumnName;
                    if (dr[colname] != DBNull.Value)
                    {
                        item.SetValue(t, dr[colname], null);
                    }
                }
                lt.Add(t);

            }
            dr.Close();
            idb.Close();
            return lt;
        }
 

        /// <summary>
        /// 将视图数据返回至DataTable
        /// </summary>
        /// <returns></returns>
        public  DataTable  GetDataViewForDataTable()
        {
            string tablename = ((Keel.ORM.DataViewAttribute)((typeof(T)).GetCustomAttributes(typeof(Keel.ORM.DataViewAttribute), true)[0])).ViewName ;
            string sql = Encoding.Default.GetString(Convert.FromBase64String( ((Keel.ORM.DataViewAttribute)((typeof(T)).GetCustomAttributes(typeof(Keel.ORM.DataViewAttribute), true)[0])).SQLString)) ;
            DataTable dt = idb.ExecuteFillDataTable(sql);
            dt.TableName = tablename;
            return dt;

        }

        #endregion

        #region select 部分
        /// <summary>
        /// 根据filter得到一个实体，该方法调用了SelectEntitys,取了第一个实体.
        /// </summary>
        /// <param name="filter">条件</param>
        /// <returns>返回一个实体，如果没有查询到则返回null</returns>
        public T SelectEntity(string filter)
        {
            List<T> tt = SelectEntitys(filter);
            if (tt.Count > 0)
            {
                return tt[0];
            }
            else
            {
                return default(T);
            }
        }
        /// <summary>
        /// 根据filter得到实体表
        /// </summary>
        /// <param name="filter">条件</param>
        /// <returns>实体列表</returns>
        public List<T> SelectEntitys(string filter)
        {
            DbDataReader dr = null;
            List<T> lt = new List<T>();
            DbCommand dbc = CreateSelectCommand();
            if (filter != null && filter.Trim() != "")
            {
                dbc.CommandText += " WHERE " + filter;
            }
            dr = idb.GetDataReader(dbc);
            while ((dr.Read()))
            {
                T t = Activator.CreateInstance<T>();
                foreach (var item in typeof(T).GetProperties())
                {
                    string colname = ((Keel.ORM.DataFieldAttribute)item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0]).ColumnName;
                    item.SetValue(t, dr[colname], null);
                }
                lt.Add(t);
            }
            dr.Close();
            idb.Close();
            return lt ;
        }


        private  DbCommand CreateSelectCommand()
        {
            string sql = "SELECT ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;      
            string collist = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                string colname = dfa.ColumnName;
                collist += (collist != null ? "," : "") + "[" + colname + "]";
            }
            
            sql += collist + "  FROM [" + tablename + "]";
            dbc.CommandText = sql;
            return dbc;
        }
        #endregion

        #region insert 部分
        /// <summary>
        /// 插入对象
        /// </summary>
        /// <param name="t"></param>
        /// <returns>如果ID是自动生成的则返回ID,否则返回影响行数</returns>
        public int Insert(T t)
        {
            bool isauto;
            DbCommand dbc = CreateInsertCommand(t, out isauto);
            int i = idb.ExecuteNonQuery(dbc,isauto );
            return i;

        }

        /// <summary>
        /// 插入一个实体，并从数据库中获取服务器处理后的值，通常用于部分列自动生成或自动计算。
        /// </summary>
        /// <param name="t">欲插入列</param>
        /// <returns>如果主键是自动生成列则返回主键值，否则返回影响行数。</returns>
        public  int  Insert(ref T t)
        {
            bool isauto;
            string filter ;
            DbParameter dbp;
            DbCommand dbc = CreateInsertCommand(t, out isauto,out filter,out dbp  );
            int i = idb.ExecuteNonQuery(dbc, isauto);
            SelectForRef(t, isauto, ref filter, dbp, ref dbc, i);
            return i ;

        }

        private void SelectForRef(T t, bool isauto, ref string filter, DbParameter dbp, ref DbCommand dbc, int i)
        {
            dbc = CreateSelectCommand();
            if (isauto)
            {
                filter = string.Format(filter, i);
            }
            else
            {
                dbc.Parameters.Add(dbp);
            }
            dbc.CommandText += " WHERE " + filter;
            DbDataReader dr = idb.GetDataReader(dbc);
            if (dr.Read())
            {
                foreach (var item in typeof(T).GetProperties())
                {
                    string colname = ((Keel.ORM.DataFieldAttribute)item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0]).ColumnName;
                    if (dr[colname] != DBNull.Value)
                    {
                        item.SetValue(t, dr[colname], null);
                    }
                }
            }
            dr.Close();
            idb.Close();
        }

        private DbCommand CreateInsertCommand(T t, out bool isautoidentitiy)
        {
            string filter; 
            DbParameter dbp;
            return CreateInsertCommand(t, out isautoidentitiy, out filter,out dbp ); 
       
        }
        private DbCommand CreateInsertCommand(T t, out bool isautoidentitiy ,out string filter,out DbParameter dbparm)
        {
            isautoidentitiy = false;
            dbparm = null;
            filter = null;
            string sql = "INSERT INTO ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            string collist = null;
            string param = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                string colname = dfa.ColumnName;
                if ( dfa.IsKey)
                {
                    if (dfa.IsAutoIdentitiy)
                    {
                        filter = colname + " ={0}";
                        isautoidentitiy = true;
                    }
                    else
                    {
                        filter = colname + " =@" + colname;
                        dbparm = dbc.CreateParameter();
                        dbparm.DbType = Common.GetDBTypeByString(dfa.DBType);
                        dbparm.ParameterName = colname;
                        dbparm.Value = item.GetValue(t, null);
                    }
                }
                if (dfa.IsAutoIdentitiy || dfa.IsComputed) continue;
                object v = item.GetValue(t, null);
                if (v != null)
                {
                    DbParameter dp = dbc.CreateParameter();
                    dp.ParameterName = colname;
                    dp.DbType = Common.GetDBTypeByString(dfa.DBType);
                    dp.Value = item.GetValue(t, null);
                    dbc.Parameters.Add(dp);
                    collist += (collist != null ? "," : "") + "[" + colname + "]";
                    param += (param != null ? "," : "") + "@" + colname;
                }
            }
            sql += "  (" + collist + ")      VALUES (" + param + " );";
            dbc.CommandText = sql;
            return dbc;
        }


        #endregion 

        #region update 部分

        /// <summary>
        /// 将WhereValue的非空值属性作为条件更新表中符合SetValue非空值属性的字段
        /// </summary>
        /// <param name="SetValue">所有符合where的记录将使用此对象中的非空属性中的值更新</param>
        /// <returns>返回受影响行数</returns>
        public int Update(string  filter , T SetValue)
        {

            string sql = "UPDATE ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            string wherelst = null;
            string setlst = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                object objset = item.GetValue(SetValue, null); 
                if (objset != null && !dfa.IsKey && !dfa.IsAutoIdentitiy && !dfa.IsComputed)
                {
                    setlst += (setlst != null ? "," : "") + "[" + dfa.ColumnName + "] = @set_" + dfa.ColumnName;
                    DbParameter sdp = dbc.CreateParameter();
                    sdp.ParameterName = "set_" + dfa.ColumnName;
                    sdp.DbType = Common.GetDBTypeByString(dfa.DBType);
                    sdp.Value = objset;
                    dbc.Parameters.Add(sdp);
                }
            }
            sql += " SET " + setlst;
            if (filter != null && filter.Trim() != "")
            {
                sql += " WHERE  " + wherelst;
            }
            dbc.CommandText = sql;
            int i = idb.ExecuteNonQuery(dbc);
            return i;
        }



        /// <summary>
        /// 将WhereValue的非空值属性作为条件更新表中符合SetValue非空值属性的字段
        /// </summary>
        /// <param name="WhereValue">该对象中的非空对象将作为where条件</param>
        /// <param name="SetValue">所有符合where的记录将使用此对象中的非空属性中的值更新</param>
        /// <returns>返回受影响行数</returns>
        public int Update(T WhereValue , T SetValue)
        {
   
            string sql = "UPDATE ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            string wherelst = null;
            string setlst = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                object objwhere=item.GetValue(WhereValue,null );
                  object objset=item.GetValue(SetValue,null );
                if (objwhere !=null )
                {
                    wherelst += (wherelst != null ? " AND " : "") + "[" + dfa.ColumnName + "] = @where_" + dfa.ColumnName;
                    DbParameter wdp= dbc.CreateParameter();
                    wdp.ParameterName = "where_" + dfa.ColumnName;
                    wdp.DbType =Common.GetDBTypeByString(dfa.DBType );
                    wdp.Value =objwhere ;
                    dbc.Parameters.Add(wdp );
                }
                if (objset !=null && !dfa.IsKey  && !dfa.IsAutoIdentitiy  && !dfa.IsComputed )
                {
                     setlst  +=(setlst != null ? "," : "") + "["+dfa.ColumnName+"] = @set_" +dfa.ColumnName;
                    DbParameter sdp= dbc.CreateParameter();
                    sdp.ParameterName = "set_" + dfa.ColumnName;
                    sdp.DbType =Common.GetDBTypeByString(dfa.DBType );
                    sdp.Value =objset  ;
                    dbc.Parameters.Add(sdp );
                }
            }
            sql += " SET " +  setlst  +" WHERE  "+ wherelst  ;
            dbc.CommandText = sql;
            int i = idb.ExecuteNonQuery(dbc);
            return i;
        }
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int  Update(T t)
        {
            int i = 0;
            bool isauto;
            string filter;
            DbParameter dbp;
            DbCommand dbc = CreateUpdateCommand(t, out isauto, out filter, out dbp);
            if (!isauto)
            {
                dbc.Parameters.Add(dbp);
            }
            i = idb.ExecuteNonQuery(dbc);
            return i;
        }
        /// <summary>
        /// 更新一个实体，常用于部分列为自动计算
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int Update(ref T t)
        {
            int i = 0;
            bool isauto;
            string filter;
            DbParameter dbp;
            DbCommand dbc = CreateUpdateCommand(t, out isauto, out filter, out dbp);
            if (!isauto)
            {
                dbc.Parameters.Add(dbp);
            }
            i = idb.ExecuteNonQuery(dbc);
            SelectForRef(t, isauto, ref filter, dbp, ref dbc, i);
            return i;
        }




        private DbCommand CreateUpdateCommand(T t, out bool isautoidentitiy, out string filter, out DbParameter dbparm)
        {
            isautoidentitiy = false;
            dbparm = null;
            filter = null;
            string sql = "UPDATE ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            string collist = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                string colname = dfa.ColumnName;
                if (dfa.IsKey)
                {
                    if (dfa.IsAutoIdentitiy)
                    {
                        filter = colname + " =" + item.GetValue(t, null).ToString ();//取得子送生成ID的值。 
                        isautoidentitiy = true;
                    }
                    else
                    {
                        filter = colname + " =@" + colname;
                        dbparm = dbc.CreateParameter();
                        dbparm.DbType = Common.GetDBTypeByString(dfa.DBType);
                        dbparm.ParameterName = colname;
                        dbparm.Value = item.GetValue(t, null);
                    }
                }
                if (dfa.IsAutoIdentitiy || dfa.IsComputed) continue;
                object v = item.GetValue(t, null);
                if (v != null)
                {
                    DbParameter dp = dbc.CreateParameter();
                    dp.ParameterName = colname;
                    dp.DbType = Common.GetDBTypeByString(dfa.DBType);
                    dp.Value =v  ;
                    dbc.Parameters.Add(dp);
                    collist += (collist != null ? "," : "") + "[" + colname + "] = @"+colname ;
                
                }
            }
            sql += " SET "+collist;
            dbc.CommandText = sql;
            return dbc;
        }

        #endregion 

        
        #region delete 部分
        public int Delete(string  filter)
        {
            string sql = "DELETE FROM  ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            DbCommand dbc = idb.CreateDbCommand();
            if (filter != null && filter.Trim() != "")
            {
                sql += " WHERE  " + filter;
            }
            dbc.CommandText = sql;
            int i = idb.ExecuteNonQuery(dbc);
            return i;
        }
        /// <summary>
        /// 将t作为where条件，删除所有符合条件的内容。
        /// </summary>
        /// <param name="t">实体，用于where条件，空属性(值为null)将忽略</param>
        /// <returns>返回受影响的行数</returns>
        public int Delete(T t)
        {
            int i = 0;
            string sql = "DELETE FROM  ";
            string tablename = ((Keel.ORM.DataTableAttribute)typeof(T).GetCustomAttributes(typeof(Keel.ORM.DataTableAttribute), true)[0]).TableName;
            sql += "[" + tablename + "]";
            string wherelst = null;
            DbCommand dbc = idb.CreateDbCommand();
            foreach (var item in typeof(T).GetProperties())
            {
                DataFieldAttribute dfa = item.GetCustomAttributes(typeof(Keel.ORM.DataFieldAttribute), true)[0] as DataFieldAttribute;
                if (dfa == null) continue;
                object objwhere = item.GetValue(t, null);

                if (objwhere != null)
                {
                    wherelst += (wherelst != null ? " AND " : "") + "[" + dfa.ColumnName + "] = @where_" + dfa.ColumnName;
                    DbParameter wdp = dbc.CreateParameter();
                    wdp.ParameterName = "where_" + dfa.ColumnName;
                    wdp.DbType = Common.GetDBTypeByString(dfa.DBType);
                    wdp.Value = objwhere;
                    dbc.Parameters.Add(wdp);
                }
            }
            sql += " WHERE  " + wherelst;
            dbc.CommandText = sql;
            i = idb.ExecuteNonQuery(dbc);
            return i;
        }
        #endregion 

        #region id计算使用方法和对象序列化
        /// <summary>
        /// 将一个对象转换为实体隐射后的base64编码，其后带有md5验证
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string ToBase64Str(T obj)
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.AssemblyFormat = FormatterAssemblyStyle.Simple;
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            string md = GetMD5(ms.ToArray());
            string str = Convert.ToBase64String(ms.ToArray()) + " " + md + System.Environment.NewLine;
            return str;
        }
        /// <summary>
        /// 将使用ToBase64Str得到的字符串转换为对象
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public  T FromBase64Str(string str)
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.AssemblyFormat = FormatterAssemblyStyle.Simple;

            string[] tmpary = str.Split(" ".ToCharArray());
            byte[] binary = Convert.FromBase64String(tmpary[0]);
            MemoryStream ms = new MemoryStream(binary);
            T obj = (T)bf.Deserialize(ms);
            string md = GetMD5(binary);
            if (md == tmpary[1].Trim())
            {
                return obj;
            }
            else
            {
                return default(T);
            }
        }
        /// <summary>
        /// 提供一个guid的快捷方式
        /// </summary>
        /// <returns></returns>
        public Guid  GetNewGuid()
        {
            return Guid.NewGuid();
        }
        /// <summary>
        /// 使用类型名称和guid的Md5作为ID.
        /// </summary>
        /// <returns>返回值为32位</returns>
        public string GetID()
        {
            string id = typeof(T).Name + Guid.NewGuid().ToString();
            return GetMD5(id);
        }
        /// <summary>
        /// 使用类型名称和guid的Md5作为ID.
        /// </summary>
        public string GetID(int lenght )
        {
            return GetID().Substring(0,lenght );
        }
        /// <summary>
        /// 使用类型名称和guid的Md5作为ID.
        /// </summary>
        public string GetID(int start ,int lenght)
        {
            return GetID().Substring(start , lenght);
        }
        /// <summary>
        /// 如果你确认某个字段或和当前数据相关的某字符串在该表中永远不重复，那么你可以使用他和表名的md5作为ID
        /// </summary>
        /// <param name="defaultstring"></param>
        /// <returns></returns>
        public string GetID(string defaultstring)
        {
            string id = typeof(T).Name + defaultstring;
            return GetMD5(id);
        }
        /// <summary>
        /// 如果你确认某个字段或和当前数据相关的某字符串在该表中永远不重复，那么你可以使用他和表名的md5作为ID
        /// </summary>
        public string GetID(string defaultstring,int lenght)
        {
            return GetID(defaultstring ).Substring(0, lenght);
        }
        /// <summary>
        /// 如果你确认某个字段或和当前数据相关的某字符串在该表中永远不重复，那么你可以使用他和表名的md5作为ID
        /// </summary>
        /// <param name="defaultstring"></param>
        /// <param name="start"></param>
        /// <param name="lenght"></param>
        /// <returns></returns>
        public string GetID(string defaultstring,int start, int lenght)
        {
            return GetID(defaultstring ).Substring(start, lenght);
        }
        /// <summary>
        /// 返回制定字符串的32位md5值
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public  string GetMD5(string txt)
        {
            return GetMD5(System.Text.Encoding.Default.GetBytes(txt));
        }
        /// <summary>
        /// 获得指定的二进制数组的32位md5值
        /// </summary>
        /// <param name="binary"></param>
        /// <returns></returns>
        public string GetMD5(byte[] binary)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(binary ));
            t2 = t2.Replace("-", "");
            return t2;
        }


        /// <summary>
        /// 将一个结构转换为字符串
        /// </summary>
        /// <param name="t"></param>
        /// <returns>返回一个字符串</returns>
        public   string StructToString(T t)
        {
            int rawsize = Marshal.SizeOf(t );//得到内存大小
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);//分配内存
            Marshal.StructureToPtr(t , buffer, true);//转换结构
            byte[] rawdatas = new byte[rawsize];
            Marshal.Copy(buffer, rawdatas, 0, rawsize);//拷贝内存
            Marshal.FreeHGlobal(buffer); //释放内存
            return Encoding.Default.GetString(rawdatas);
        }
        /// <summary>
        /// 将一个字符串装转换为结构
        /// </summary>
        /// <param name="s"></param>
        /// <returns>返回一个结构</returns>
        public T  StringToStruct(string s)
        {
            Type anytype = typeof(T );
            T t = default(T);
            byte[] rawdatas = Encoding.Default .GetBytes(s);
            int rawsize = Marshal.SizeOf(anytype);
            if (rawsize > rawdatas.Length)
                t  =(T)Activator.CreateInstance(typeof (T ));
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawdatas, 0, buffer, rawsize);
            object retobj = Marshal.PtrToStructure(buffer, anytype);
            Marshal.FreeHGlobal(buffer);
            t  = (T )retobj;
            return t;
        }
        #endregion 
    }
}
